package com.example.zxapigateway.filters;

import cn.hutool.core.text.AntPathMatcher;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.zx.zxapicommon.common.BaseResponse;
import com.zx.zxapicommon.service.InnerUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 全局处理过滤器
 *
 * @author 张旭
 * @version 1.0
 */
@Component
@Slf4j
public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @DubboReference
    private InnerUserService innerUserService;


    //不需要登录就能访问的地址
    public static final List<String> NOT_LOGIN_PATH = Arrays.asList("/api/apiclient", "/api/user/**");

    //需要登录才能进行访问
    private static final List<String> NEED_LOGIN_PATH = Arrays.asList("/api/userInterfaceInfo/**", "/api/interfaceInfo/**", "/api/auth/**", "/api/oauth/**", "/api/order/**", "/api/alipay/**");

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        String path = request.getPath().value();

        //打印当前请求日志
        log.info("请求唯一id：" + request.getId());
        log.info("请求参数：" + request.getMethod());
        log.info("请求路径：" + path);
        String method = request.getMethod().toString();
        log.info("请求参数：" + method);
        String address = request.getRemoteAddress().getHostString();
        log.info("请求主机地址:" + address);

        //判断当前请求的地址是否需要登录
        List<Boolean> collect = NOT_LOGIN_PATH.stream().map(notLoginPath -> {
            AntPathMatcher antPathMatcher = new AntPathMatcher();
            return antPathMatcher.match(notLoginPath, path);
        }).collect(Collectors.toList());
        if (collect.contains(true)) {
            //当前的请求不需要登录,直接放行
            return chain.filter(exchange);
        }

        //其他类型的请求都需要判断用户是否登录
        String cookie = request.getHeaders().getFirst("Cookie");

        String loginUserVo = HttpRequest.post("http://117.72.8.188:8082/api/user/checkUserLogin")
                .header("Cookie", cookie)
                .timeout(20000)
                .execute().body();

        JSONObject entries = JSONUtil.parseObj(loginUserVo);
        BaseResponse baseResponse = JSONUtil.toBean(entries, BaseResponse.class);

        Object data = baseResponse.getData();

        if (null == data) {
            return handleNoAuth(response);
        }

        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }

    private Mono<Void> handleNoAuth(ServerHttpResponse response) {
        response.setStatusCode(HttpStatus.FORBIDDEN);
        return response.setComplete();
    }
}
